package cn.admin.remoting.util;

import java.util.concurrent.*;

public class TrScheduledExecutor extends ScheduledThreadPoolExecutor {


    public TrScheduledExecutor(final String threadName) {
        super(1, r -> new Thread(r,threadName));
    }

    public int getPendingCount() {
        return this.getQueue().size();
    }

    @Override
    protected <V> RunnableScheduledFuture<V> decorateTask(Runnable runnable,
                                                          RunnableScheduledFuture<V> task) {
        return new FutureDecorator<>(task);
    }

    @Override
    protected <V> RunnableScheduledFuture<V> decorateTask(Callable<V> callable,
                                                          RunnableScheduledFuture<V> task) {
        return new FutureDecorator<>(task);
    }

    class FutureDecorator<V> implements RunnableScheduledFuture<V> {

        final RunnableScheduledFuture<V> delegate;

        FutureDecorator(RunnableScheduledFuture<V> delegate) {
            this.delegate = delegate;
        }

        @Override
        public boolean isPeriodic() {
            return this.delegate.isPeriodic();
        }

        @Override
        public long getDelay(TimeUnit unit) {
            return this.delegate.getDelay(unit);
        }

        @Override
        public int compareTo(Delayed o) {
            return this.delegate.compareTo(o);
        }

        @Override
        public void run() {
            this.delegate.run();
        }

        @Override
        public boolean cancel(boolean mayInterruptIfRunning) {
            boolean isOk = this.delegate.cancel(mayInterruptIfRunning);
            if (isOk) {
                TrScheduledExecutor.this.getQueue().remove(this);
            }
            return isOk;
        }

        @Override
        public boolean isCancelled() {
            return this.delegate.isCancelled();
        }

        @Override
        public boolean isDone() {
            return this.delegate.isDone();
        }

        @Override
        public V get() throws InterruptedException, ExecutionException {
            return this.delegate.get();
        }

        @Override
        public V get(long timeout, TimeUnit unit) throws InterruptedException,
                ExecutionException, TimeoutException {
            return this.delegate.get(timeout,unit);
        }
    }
}
